import copy
import os
from typing import List

from ninja import Router, Query
from ninja.pagination import paginate
from django.db import transaction

from apps.commom.good import GoodsResponseSchema, GoodSerializer, GoodSpecificationSerializer, GoodTypeSerializer
from apps.manager.good_manager.schemas import ManagerGoodsFiltersSchema, ManagerGoodsStatusOpSchema, GoodsAddSchema,\
    GoodsUpdateSchema, GoodTypeAddSchema

from apps.schemas import R
from models.models import Goods, GoodType, GoodPicture, GoodSpecification
from utils.auth import ManagerAuthBearer
from utils.decorators import handle_exception
from utils.paginations import MyPagination
from utils.snowflake import snowflake

good_manager_router = Router(tags=["商品管理"], auth=ManagerAuthBearer())


@good_manager_router.get("/goods", summary="获取商品列表", response=List[GoodsResponseSchema])
@paginate(MyPagination)
@handle_exception("获取商品列表车失败")
def get_goods(request, filters: ManagerGoodsFiltersSchema = Query(...)):
    goods = Goods.objects.all()
    goods = filters.filter(goods)
    return goods


@good_manager_router.post("/good/status_op", summary="修改商品状态")
@handle_exception("修改商品状态失败")
def status_op(request, data: ManagerGoodsStatusOpSchema):
    good = Goods.objects.get(id=data.id)
    good.status = data.status
    good.asave()
    return R.ok(msg="操作成功")


@good_manager_router.post("/good", summary="添加商品")
@handle_exception("添加商品失败")
def add_good(request, data: GoodsAddSchema):
    with transaction.atomic():
        good_base_data = copy.deepcopy(data.dict())
        del good_base_data["specs"]
        del good_base_data["files"]
        new_good = Goods.objects.create(**good_base_data)
        for file in data.files:
            GoodPicture.objects.create(good=new_good, picture=file)
        for spec in data.specs:
            GoodSpecification.objects.create(**spec.dict(), good=new_good)
    return R.ok(msg="添加成功")


@good_manager_router.put("/good/{good_id}", summary="修改商品")
@handle_exception("修改商品失败")
def update_good(request, good_id, data: GoodsUpdateSchema):
    with transaction.atomic():
        op_good = Goods.objects.get(id=good_id)
        good_base_data = copy.deepcopy(data.dict())
        del good_base_data["specs"]
        del good_base_data["upload_files"]
        Goods.objects.filter(pk=good_id).update(**good_base_data)
        # todo 图片相比之前的图片，删除多余图片，添加新图片
        origin_pic_names = [os.path.split(item)[1] for item in GoodPicture.objects.filter(good=good_id).values_list("picture", flat=True)]
        update_pic_names = [os.path.split(item)[1] for item in data.upload_files]
        deleted_pic = set(origin_pic_names).difference(update_pic_names)
        new_pic = set(update_pic_names).difference(origin_pic_names)
        for delete_item in deleted_pic:
            delete_obj = GoodPicture.objects.filter(good=good_id, picture=delete_item).first()
            delete_obj.delete()
            os.remove(f"static/good/{delete_item}")
        folder = f"static/good"
        for new_item in new_pic:
            prefix, suffix = os.path.splitext(new_item)
            save_path = f"{folder}/{prefix}-{snowflake()}{suffix}"
            GoodPicture.objects.create(good=op_good, picture=save_path)
        # todo 商品规则更新
        for spec in data.specs:
            spec_data = spec.dict()
            GoodSpecification.objects.filter(pk=spec_data["id"]).update(**spec_data)
    return R.ok(msg="修改成功")


@good_manager_router.get("/good/{good_id}", summary="获取商品详情")
@handle_exception("获取商品详情失败")
def get_good(request, good_id):
    good = Goods.objects.get(id=good_id)
    return R.ok(GoodSerializer(good).data)


@good_manager_router.delete("/good/{good_id}", summary="删除商品")
@handle_exception("删除商品失败")
def delete_good(request, good_id):
    if not Goods.objects.filter(id=good_id).exists():
        return R.fail("商品不存在")
    with transaction.atomic():
        GoodSpecification.objects.filter(good=good_id).delete()
        good_pics = GoodPicture.objects.filter(good=good_id)
        for item in good_pics:
            os.remove(item.picture)
            item.delete()
        Goods.objects.get(id=good_id).delete()
    return R.ok(msg="删除成功")


@good_manager_router.post("/good_type/add", summary="添加商品类型")
@handle_exception("添加商品类型失败")
def add_good_type(request, data: GoodTypeAddSchema):
    GoodType.objects.create(name=data.name)
    return R.ok(msg="添加成功")


@good_manager_router.get("/good_types", summary="获取所有商品类型")
@handle_exception("获取所有商品类型失败")
def get_good_types(request):
    types = GoodType.objects.all()
    return R.ok(data=GoodTypeSerializer(types, many=True).data)


@good_manager_router.get("/good_type/{good_type_id}", summary="获取商品类型详情")
@handle_exception("获取商品类型详情失败")
def get_good_type(request, good_type_id: int):
    good_type = GoodType.objects.get(id=good_type_id)
    return R.ok(data=GoodTypeSerializer(good_type).data)


@good_manager_router.put("/good_type/{good_type_id}", summary="修改商品类型")
@handle_exception("修改商品类型失败")
def update_good_type(request, good_type_id: int, data: GoodTypeAddSchema):
    good_type = GoodType.objects.get(id=good_type_id)
    good_type.name = data.name
    good_type.save()
    return R.ok(msg="修改成功")


@good_manager_router.delete("/good_type/{good_type_id}", summary="删除商品类型")
@handle_exception("删除商品类型失败")
def delete_good_type(request, good_type_id: int):
    if not GoodType.objects.filter(id=good_type_id).exists():
        return R.fail("商品类型不存在")
    good_type = GoodType.objects.get(id=good_type_id)
    good_type.delete()
    return R.ok(msg="删除成功")
